package unittestexample;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class Person {

    private static String DATE_FORMAT_STRING = "dd.MM.yyyy";
    private String name;
    private Date birthDate;

    public Person() {
    }

    /**
     * 
     * @param dateString Datumsstring, der im TT.MM.YYYY Format vorliegen muss,
     * wenn er korrekt konvertierbar sein soll
     * @return isCorrect true, wenn konvertierbar, sonst false
     */
    public boolean isCorrectDate(String dateString) {

        boolean isCorrect = true;

        Date parsedDate = null;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_STRING);
            parsedDate = sdf.parse(dateString);
        } catch (ParseException ex) {
            isCorrect = false;
        }
        return isCorrect;
    }

    private Date convertDateStringToDate(String dateString) {

        Date parsedDate = null;

        try {
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_STRING);
            sdf.setLenient(false);
            parsedDate = sdf.parse(dateString);
        } catch (ParseException ex) {
            //Rethrow a new BusinessException with ParseException as cause
            throw new BusinessException("cannot convert String " + dateString + " to date", ex);
        }
        return parsedDate;
    }

    private int calcAgeFormel(Date dateOfBirth) {
        int age = -1;

        if (dateOfBirth != null) {

            GregorianCalendar now = new GregorianCalendar();
            int y, m, d;
            y = now.get(Calendar.YEAR);
            m = now.get(Calendar.MONTH);
            d = now.get(Calendar.DAY_OF_MONTH);

            GregorianCalendar birthDateCal = new GregorianCalendar();
            birthDateCal.setTime(dateOfBirth);

            age = y - birthDateCal.get(Calendar.YEAR);
            if ((m < birthDateCal.get(Calendar.MONTH))
                    || ((m == birthDateCal.get(Calendar.MONTH)) && (d < birthDateCal.get(Calendar.DAY_OF_MONTH)))) {
                --age;
            }
        }
        return age;
    }

    private long calcAgeInDays(Date dateOfBirth) {

        long delta_in_Tagen = 0;

        if (dateOfBirth != null) {
            Calendar cal_birthday = Calendar.getInstance();
            cal_birthday.setTime(dateOfBirth);
            Calendar cal_now = Calendar.getInstance();
            //System.out.println("" + cal_birthday + "  " + cal_now);
            delta_in_Tagen = Math.round(
                    (double) ((cal_now.getTimeInMillis() - cal_birthday.getTimeInMillis()) / (1000. * 60. * 60. * 24.)));
        }
        return delta_in_Tagen;
    }

    public long getAgeInDays() {

        long delta_in_Tagen = this.calcAgeInDays(birthDate);
        return delta_in_Tagen;
    }

    public int calcAge() {

        return calcAgeFormel(this.birthDate);
    }

    private Date getBirthDate() {
        return birthDate;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * Nimmt einen Datumstring entgegen, konvertiert diesen zu einem Java-Datum
     * und setzt diesen als Geburtsdatum der Person.
     * @param birthdayAsString Datumsstring, der im TT.MM.YYYY Format vorliegen muss
     */
    public void setBirthDateByString(String birthdayAsString) {

        this.birthDate = convertDateStringToDate(birthdayAsString);

    }

    public String getBirthDateAsString() {
        String dateString = null;

        if (birthDate != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_STRING);
            dateString = sdf.format(birthDate);
        }
        return dateString;
    }
}
